using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Common;
using System.Drawing;

namespace ProduceApp.Tools
{
    /// <summary>
    /// 打印帮助类
    /// </summary>
    public class PrintHelper
    {
        #region constructor and properties

        /// <summary>
        /// 需要打印的内容
        /// </summary>
        public List<PrintInfo> PrintInfos { get; set; }

        public PrintHelper()
        {

        }

        #endregion

        /// <summary>
        /// 打印
        /// </summary>
        /// <param name="g"></param>
        public void Print(Graphics g)
        {
            if (this.PrintInfos != null && this.PrintInfos.Count > 0)
            {

                foreach (PrintInfo p in this.PrintInfos)
                {
                    Pen lineColor = new Pen(p.PrtColor, 0.2f);

                    switch (p.PrtType)
                    {
                        case PrintType.Text:
                            Font tFont = new Font(p.FontFamily, p.FontSize, p.FontStyle);
                            Brush b = new SolidBrush(p.PrtColor);
                            g.DrawString(p.Content, tFont, b, p.Start);
                            break;
                        case PrintType.TextMulti:
                            Font tFont1 = new Font("微软雅黑", p.FontSize, p.FontStyle);
                            Brush b1 = new SolidBrush(p.PrtColor);
                            g.DrawString(AutomaticLine(p.Content,p.minWidth,p.Width), tFont1, b1, p.Start);
                            break;
                        case PrintType.Table:
                            float distance_h = (p.End.Y - p.Start.Y) * 1.0f / p.Row;//横线之间的间距
                            float distance_w = (p.End.X - p.Start.X) * 1.0f / p.Column;//竖线之间的间距
                            for (int i = 0; i < p.Row + 1; i++)
                            {
                                //画横线
                                float y = p.Start.Y + (i) * distance_h;
                                g.DrawLine(lineColor, new PointF(p.Start.X, y), new PointF(p.End.X, y));
                            }
                            for (int i = 0; i < p.Column + 1; i++)
                            {
                                //画竖线
                                float x = p.Start.X + (i) * distance_w;
                                g.DrawLine(lineColor, new PointF(x, p.Start.Y), new PointF(x, p.End.Y));
                            }
                            break;
                        case PrintType.Line:
                            g.DrawLine(lineColor, new PointF(p.Start.X, p.Start.Y), new PointF(p.End.X, p.End.Y));
                            break;
                        case PrintType.Shape:
                            g.DrawRectangle(lineColor, p.Start.X, p.Start.Y,p.Width,p.Height);
                            break;
                        case PrintType.FillRectangle:
                            Brush bg = new SolidBrush(p.PrtColor);

                            g.FillRectangle(bg, p.Start.X, p.Start.Y, p.Width, p.Height);
                            break;
                        case PrintType.Barcode:
                            g.DrawImage(GetPrintImage(p.Content), p.Start.X, p.Start.Y, p.Width, p.Height);

                            break;

                        default:
                            break;
                    }
                }
                g.Dispose();
            }
        }

        #region 条码
        /// <summary>
        /// 打印条形码图片
        /// 在生成条形码时，大小是不可以任意放大的，那么我们如果想任意改变条形码大小
        /// 思路：
        /// 1.把条形码生成为图片
        /// 2.改变条形码图片的大小就可以了
        /// </summary>
        /// <returns></returns>
        public Image GetPrintImage(string StrCode128 = "1234567")
        {
            BarcodeLib.Barcode b = new BarcodeLib.Barcode();
            //设置条形码宽度和高度
            int W = Convert.ToInt32(250);
            int H = Convert.ToInt32(80);
            //对齐方式：默认居中
            b.Alignment = BarcodeLib.AlignmentPositions.CENTER;
            //条码格式
            BarcodeLib.TYPE type = BarcodeLib.TYPE.CODE128;
            //显示生成条形码的内容
            b.IncludeLabel = true;

            b.RotateFlipType = RotateFlipType.RotateNoneFlipNone;
            //生成条形码内容的位置
            b.LabelPosition = BarcodeLib.LabelPositions.BOTTOMCENTER;

            Font font = new Font("verdana", 8f);//字体设置
            b.LabelFont = font;

            //b.Encode(条形码格式,要生成条形码的内容,条形码颜色,条形码背景色,宽度,高度)
            Image image = b.Encode(type, StrCode128, Color.Black, Color.White, W, H);
            return image;
        }
        #endregion

        #region 打印字符串自动换行

        /// <summary>    
        /// 字符串自动换行。最短intLenMin，最长intLenMax。
        /// </summary>    
        /// <param name="strOldText">原字符串</param>    
        /// <param name="intLenMin">最短字节长度</param>    
        /// <param name="intLenMax">最长字节长度</param>    
        /// <returns>string</returns>    
        /// <remarks></remarks>    
        public static string AutomaticLine(string strOldText, int intLenMin, int intLenMax)
        {
            int intLength = 0;
            string strResult = "";

            //获取原字符串的字节长度    
            intLength = System.Text.Encoding.GetEncoding("gb2312").GetByteCount(strOldText);

            if (intLength > intLenMax)
            {
                //总字节数> 最长截取的最长字节数，    
                //则截取最长字节数, 然后对剩余字符串再处理

                //获取字符串的UCS2码    
                byte[] bytes = System.Text.Encoding.Unicode.GetBytes(strOldText);
                //获取字符的实际截取位置    
                int intCutPos = RealCutPos(bytes, intLenMax);
                //采用递归调用    
                strResult = System.Text.Encoding.Unicode.GetString(bytes, 0, intCutPos * 2) + "\r\n" + AutomaticLine(strOldText.Substring(intCutPos), intLenMin, intLenMax);
            }
            else if (intLength > intLenMin)
            {
                //如果 最长字节数 >总字节数 > 最短字节数，则 换行，并补齐空格到最短字节数位置    
                strResult = strOldText + "\r\n";// +"".PadRight(intLenMin);
            }
            else
            {
                //如果 总字节数 < 最短字节数，则直接补齐空格到最短字节数的位置    
                strResult = strOldText;// +"".PadRight(intLenMin - intLength);
            }
            return strResult;
        }

        /// <summary>    
        /// 返回字符的实际截取位置    
        /// </summary>    
        /// <param name="bytes">UCS2码</param>    
        /// <param name="intLength">要截取的字节长度</param>    
        /// <returns></returns>    
        /// <remarks></remarks>    
        private static int RealCutPos(byte[] bytes, int intLength)
        {
            //获取UCS2编码    
            int intCountB = 0;
            // 统计当前的字节数     
            int intCutPos = 0;
            //记录要截取字节的位置      

            while ((intCutPos < bytes.GetLength(0) && intCountB < intLength))
            {
                // 偶数位置，如0、2、4等，为UCS2编码中两个字节的第一个字节    
                if (intCutPos % 2 == 0)
                {
                    // 在UCS2第一个字节时，字节数加1    
                    intCountB += 1;
                }
                else
                {
                    // 当UCS2编码的第二个字节大于0时，该UCS2字符为汉字，一个汉字算两个字节    
                    if (bytes[intCutPos] > 0)
                    {
                        intCountB += 1;
                    }
                }
                intCutPos += 1;
            }

            // 如果intCutPos为奇数时，处理成偶数      
            if (intCutPos % 2 == 1)
            {
                // 该UCS2字符是汉字时，去掉这个截一半的汉字    
                if (bytes[intCutPos] > 0)
                {
                    intCutPos = intCutPos - 1;
                }
                else
                {
                    // 该UCS2字符是字母或数字，则保留该字符    
                    intCutPos = intCutPos + 1;
                }
            }

            return intCutPos / 2;
        }
        #endregion


    }

    public class PrintInfo
    {

        /// <summary>
        /// 打印类型
        /// </summary>
        public PrintType PrtType { get; set; }

        /// <summary>
        /// 打印颜色
        /// </summary>
        public Color PrtColor { get; set; } = Color.Black;

        /// <summary>
        /// 起始位置
        /// </summary>
        public Point Start { get; set; }

        /// <summary>
        /// 结束位置
        /// </summary>
        public Point End { get; set; }

        /// <summary>
        /// 字体大小
        /// </summary>
        public int FontSize { get; set; } = 10;

        public FontStyle FontStyle { get; set; }
        public FontFamily FontFamily { get; set; } = new FontFamily("黑体");
        
        /// <summary>
        /// 打印内容
        /// </summary>
        public string Content { get; set; }

        /// <summary>
        /// 列数
        /// </summary>
        public int Column { get; set; }

        /// <summary>
        /// 行数
        /// </summary>
        public int Row { get; set; }

        public int Width { get; set; }
        public int minWidth { get; set; }
        public int Height { get; set; }
    }

    /// <summary>
    /// 打印类型
    /// </summary>
    public enum PrintType
    {
        Text = 0,
        Table = 1,
        Line=2,
        Shape = 3,
        Barcode=4,
        FillRectangle=5,
        TextMulti = 6



    }

}
